package cn.myzf.fort.access.exe;



import cn.myzf.fort.access.accesscommon.core.AbstractBinaryWithTimeout;
import cn.myzf.fort.access.accesscommon.core.Binaries;
import cn.myzf.fort.access.accesscommon.core.Utils;

import java.util.ArrayList;
import java.util.List;

public class PLink extends AbstractBinaryWithTimeout {

    protected boolean verbose;

    protected boolean compression;

    protected boolean noShell;

    protected boolean overWritePid;

    protected String sshPort;

    protected String sshPw;

    protected String sshUser;

    protected String sshHost;

    protected String sock5Host;

    protected String sock5Port;

    protected String logName;

    public PLink sshPort(String sshPort){
        this.sshPort = sshPort;
        return this;
    }


    public PLink sshPw(String sshPw){
        this.sshPw = sshPw;
        return this;
    }

    public PLink sshUser(String sshUser){
        this.sshUser = sshUser;
        return this;
    }

    public PLink sshHost(String sshHost){
        this.sshHost = sshHost;
        return this;
    }

    public PLink sock5Host(String sock5Host){
        this.sock5Host = sock5Host;
        return this;
    }

    public PLink sock5Port(String sock5Port){
        this.sock5Port = sock5Port;
        this.foward_info = getDynamicSock5PortForward();
        return this;
    }

    public PLink logName(String logName){
        this.logName = logName;
        return this;
    }


    public PLink setOverWritePid(boolean overWritePid) {
        this.overWritePid = overWritePid;
        return this;
    }

    protected String dynamicSock5PortForward;

    public String getDynamicSock5PortForward() {
        return dynamicSock5PortForward = getSock5Host()+":"+getSock5Port();
    }

    public void reset() {
        super.reset();
        verbose = true;
        compression = true;
        noShell = true;
        dynamicSock5PortForward = "";
        sshPort = "";
        sshPw = "";
        sshUser = "";
        sshHost = "";
        sock5Host = "127.0.0.1";
        sock5Port = "1080";
        logName = "log";
    }

    @Override
    public Boolean checkOccupancy() throws Exception {
        if (overWritePid) {
            Utils.killProcess(Utils.checkListening(getDynamicSock5PortForward()));
            return true;
        }
        if (Utils.checkListening(getDynamicSock5PortForward()).isEmpty()) return true;
        return false;
    }


    /**
     *  -v show verbose messages
     */

    public boolean isVerbose() {
        return verbose;
    }

    /**
     *  -C enable compression
     */

    public boolean isCompression() {
        return compression;
    }

    /**
     *  -N  don't start a shell/command (SSH-2 only)
     */

    public boolean noShell() {
        return noShell;
    }

    /**
     *  -P port  connect to specified port
     */

    public String getSshPort() {
        return sshPort;
    }

    /**
     *  -D [listen-IP:]listen-port
     *   Dynamic SOCKS-based port forwarding
     */



    /**
     * -pw passw login with specified password
     */

    public String getSshPw() {
        return sshPw;
    }

    public String getSshUser() {
        return sshUser;
    }

    /**
     *
     */

    public String getSshHost() {
        return sshHost;
    }


    public String getSshUrl() {
        return getSshUser()+"@"+getSshHost();
    }

    /**
     *
     */
    public String getSock5Host() {
        return sock5Host;
    }
    /**
     *
     */

    public String getSock5Port() {
        return sock5Port;
    }



    public String getLogName() {
        return logName;
    }

    public String getLogUrl() {
        return "> "+getLogName() + ".log "+ "2>&1";
    }

    @Override
    public List<String> commandLineArgs() throws Exception {
        List<String>  result;
        String binary;

        //获取执行路径
        binary = Binaries.rsyncBinary();
        result = options();
        result.add(0,binary);
   /*     if (SystemUtils.IS_OS_WINDOWS) {
            result.add(0,"/c");
            result.add(0,"cmd");
        }*/
        //获取执行参数
        return result;
    }


    public List<String> options() throws Exception {
        List<String> 	result;

        result = new ArrayList<>();

        if (getSshHost().isEmpty())
            throw new IllegalStateException("No sshHost defined!");
        if (getSshUser().isEmpty())
            throw new IllegalStateException("No sshUser defined!");
        if (getSshPw().isEmpty())
            throw new IllegalStateException("No sshPassWord defined!");
        if (getSock5Host().isEmpty())
            throw new IllegalStateException("No sock5 Host defined!");
        if (getSock5Port().isEmpty())
            throw new IllegalStateException("No sock5 Port defined!");

        if (isVerbose()) result.add("-v");
        if (isCompression()) result.add("-C");
        if (noShell()) result.add("-N");
        if (!getSshPort().isEmpty()) result.add("-P");
        result.add(getSshPort());
        result.add("-pw");
        result.add(getSshPw());
        result.add(getSshUrl());
        result.add("-D");
        result.add(getDynamicSock5PortForward());
                return result;
    }
}
